package cn.getech.data.development.constant;

import cn.getech.data.intelligence.common.utils.RegexUtils;
import com.google.common.collect.Lists;
import lombok.Getter;

import java.util.*;

@Getter
public enum TableDataType {

    INT("INT"),
    BIGINT("BIGINT"),
    FLOAT ("FLOAT"),
    DOUBLE ("DOUBLE"),

    BOOLEAN("BOOLEAN"),

    STRING("STRING"),
    DATE ("DATE"),
    //Error while compiling statement: FAILED: SemanticException [Error 10099]: DATETIME type isn't supported yet. Please use DATE or TIMESTAMP instead
    DATETIME ("DATETIME"),
    SQLINJECT ("SQLINJECT"),
    //用datetime来代替
    TIMESTAMP("TIMESTAMP");


    TableDataType(String name) {
        this.name = name;
    }


    private String name;

    public static boolean containsName(String name) {
        if (name == null) {
            return false;
        }
        for (TableDataType t : TableDataType.values()) {
            if (t.getName().equalsIgnoreCase(name)) {
                return true;
            }
        }
        return false;
    }

    public static List<String> getValues() {
        List<String> values = Lists.newArrayList();
        for (TableDataType value : TableDataType.values()) {
            values.add(value.getName());
        }
        return values;
    }


    public static boolean isStringOrDate(String name) {
        if (name.contains("DATE") || name.contains("STRING") || name.contains("TIMESTAMP"))
            return true;
        else
            return false;
    }

    /**
     * 把分区信息转成map
     *
     * @return
     */
    public static Map<String, Set<String>> partitionListToMap(List<String> partitions) {
        Map<String, Set<String>> partitionsMap = new HashMap<>();
        Set<String> partitionVals;
        for (String partition : partitions) {
            String[] values = partition.split("=");
            if (values.length != 2) continue;
            String key = values[0];
            String val = values[1].replaceAll("'", "");
            partitionVals = partitionsMap.get(key) == null ? new HashSet<>() : partitionsMap.get(key);
            partitionVals.add(val.trim());
            partitionsMap.put(key, partitionVals);
        }
        return partitionsMap;
    }

    public static boolean checkValueAndType(String dataType, String data) {
        if (dataType == null || data == null) {
            return false;
        }
        for (TableDataType t : TableDataType.values()) {
            if (t.getName().equalsIgnoreCase(dataType)) {
                if (t.getName().equals(INT.getName())) {
                    return RegexUtils.checkDigit(data);
                } else if (t.getName().equals(BIGINT.getName())) {
                    for (int i = 0; i < data.length(); i++) {
                        if (!Character.isDigit(data.charAt(i))) {
                            if (i == data.length() - 1 && "l".equalsIgnoreCase(String.valueOf(data.charAt(i)))) {
                                return true;
                            }
                            return false;
                        }
                    }
                    return true;
                } else if (t.getName().equals(FLOAT.getName())) {
                    return RegexUtils.checkFloats(data);
                } else if (t.getName().equals(DOUBLE.getName())) {
                    for (int i = 0; i < data.length(); i++) {
                        if (!Character.isDigit(data.charAt(i)) && !".".equals(data.charAt(i))) {
                            return false;
                        }
                    }
                    return true;
                } else if (t.getName().equals(BOOLEAN.getName())) {
                    if (data.equalsIgnoreCase("true") || data.equalsIgnoreCase("false"))
                        return true;
                    else
                        return false;
                } else if (t.getName().equals(STRING.getName()) || t.getName().equals(TIMESTAMP.getName())) {
                    return true;
                } else if (t.getName().equals(DATE.getName())) {
                    return RegexUtils.checkBirthday(data);
                } else if (t.getName().equals(DATETIME.getName())) {
                    return RegexUtils.checkDataTime(data);
                }
            }
        }
        return false;
    }
}
